/**
 * axios请求方法封装
 */
 import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'
 import { ElMessage } from 'element-plus'
 import { baseURL } from './env'
 import router from '@/router'
 import { useCommonStore } from '@/stores/common'
 import { RefreshToken } from '@/api/common'

 // 创建一个实例
const service = axios.create({
  baseURL: baseURL,
  timeout: 5000 
})

export default async function request<T>(option: AxiosOption): Promise<ServiceResponse<T>>{
  const { url, data = {}, method = 'GET',contentType = '', loading = true } = option

  const options: AxiosRequestConfig = {
    url: 'admin/' + url,
    baseURL,
    method,
    timeout: 30000,
    headers: {}
  }

  if (method === 'GET') {
    options.params = data
  } else {
    if(contentType === 'file') {
      options.data = data
      options.headers = {}
      options.headers["Content-Type"] = 'application/x-www-form-urlencoded'
    }
    else {
      options.data = JSON.stringify(data)
      options.headers = {}
      options.headers["Content-Type"] = 'application/json;charset=utf-8'
    }
    
  }
  if (contentType === 'file' || contentType === 'blob') {
    options.timeout = 12000000
  } 
  const commonStore = useCommonStore() 
  commonStore.loading = true
  const res = await axios(options)
  commonStore.loading = false
  if (res) {
    if (contentType === 'blob') {
      if (res.headers['content-type'].indexOf('application/json') > -1) {
        return res.data
      } else if (res.headers['content-type'].indexOf('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') > -1) {
        console.log(res)
       const dispositions = res.headers['content-disposition'].split(';')
        const name = decodeURI(dispositions[2]).substring(18)
        exportExcel(res.data, name)
        return { success: true }
      }
    }
    return res.data
  }

  return { success: false}
}

const exportExcel = (data:any, fileName: string) => {
  const blob = new Blob([data], { type: 'application/ms-excel' })
  const objUrl = URL.createObjectURL(blob)
  
  const a = document.createElement('a')
  a.href = objUrl
  a.download = fileName
  a.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window }))
  window.URL.revokeObjectURL(objUrl)
  return ElMessage.success('导出成功')

}

axios.interceptors.request.use(
  (config: any) => {
    config.headers.Authorization = `Bearer ${localStorage.token}`
    return config
  },
  (error) => {
    return Promise.reject(error)
  }
)

const errorType: { [key: number]: string } = {
  400: '请求错误',
  401: '未授权，请登录',
  403: '无权限访问',
  404: '请求地址出错',
  500: '系统错误，请联系管理员',
  503: '服务不可用'
}


axios.interceptors.response.use(
  (config: AxiosResponse) => {
    return config
  },
  (error) => {
    const response = error.response
    if (!response) {
      return ElMessage.error('无法连接服务器，请检查网络')
    }
    const code = response.status
    if (code === 417) {
      return ElMessage.error({
        message: response.data.msg
      })
    }
    if (code === 401) {
      if(!localStorage.refreshToken) return router.push('/login')
     
      return RefreshToken({ token: localStorage.refreshToken }).then((res: ServiceResponse<Token>) => {
        if (res.success) {
          localStorage.token = res.data?.accessToken
          localStorage.refreshToken = res.data?.refreshToken
          // 获取当前失败的请求
          const config = response.config
          //重置失败请求的配置
          config.headers = {}
          config.headers.Authorization = `Bearer ${localStorage.token}`
          return service(config)
        }
        else {
          localStorage.refreshToken = ''
          localStorage.token = ''
          router.push('/login')
        }
      })
    }
    else ElMessage.error(errorType[code])
  }
)